﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TestKontrole2 {
    public class ElementRepository : TestKontrole2.repozitorij.IElementRepository {
        private List<IElement> sviElementi;  //Simulacija elemenata u bazi
        private List<IElement> elementi;
        private static ElementRepository instanca = null;
        private Uvjet uvjetFiltriranjaElemenata;
        private Dictionary<int,int> tablicaIndeksa;
        private List<ElementKontrole> elementiKontrole;

        private ElementRepository() {
            createDefaultElemente();
            elementi = new List<IElement>();
            elementiKontrole = new List<ElementKontrole>();
            tablicaIndeksa = new Dictionary<int, int>();
            
            //TODO: Konekcija prema bazi
        }

        private void createDefaultElemente() {
            sviElementi = new List<IElement>();
            DateTime dt = new DateTime(1980, 10, 17);
            for (int i = 0; i < 100; i++) {
                Element ele = new Element(i,"Element " + i.ToString(), dt.AddMonths(i), "Element "+ i.ToString() + " " + dt.ToString());
                sviElementi.Add(ele);
            }
        }
        private ElementRepository(Uvjet uvjet):this() {
            setUvjet(uvjet);
        }
        public static ElementRepository getInstanca() {
            if(instanca == null) {
                instanca = new ElementRepository();
            }
            return instanca;
        }

        public static ElementRepository getInstanca(Uvjet uvjet) {
            if (instanca == null) {
                instanca = new ElementRepository(uvjet);
            }
            if(!uvjet.Equals(instanca.uvjetFiltriranjaElemenata)) instanca.setUvjet(uvjet);
            return instanca;
        }

        /// <summary>
        /// dodavanje novog elementa kontrole
        /// </summary>
        public void addElementKontrole(ElementKontrole element) {
            elementiKontrole.Add(element);
        }

        public IElement getElementByID(int idElementa) {
            if (tablicaIndeksa.ContainsKey(idElementa)) {
                int indeks = tablicaIndeksa[idElementa];
                return elementi[indeks];
            } else { 
                //TODO: Ako nema elementa u memoriju, vadi ga iz baze
                throw new iznimke.ElementNotExistException();
            }
        }

        /// <summary>
        /// dohvaca elemente na temelju uvjeta
        /// </summary>
        public List<IElement> getElementByUvjet(Uvjet uvjet) {
            if (!uvjetFiltriranjaElemenata.Equals(uvjet))
                setUvjet(uvjet);
            return elementi;
        }

        /// <summary>
        /// vraca broj elementa koji zadovoljavaju odre]eni uvjet
        /// </summary>
        public int getBrojElemenataByUvjet(Uvjet uvjet) {
            if (!uvjetFiltriranjaElemenata.Equals(uvjet))
                setUvjet(uvjet);
            return getBrojElemenata();
        }

        public void setUvjet(Uvjet uvjet) {
            uvjetFiltriranjaElemenata = uvjet;
            if(uvjetFiltriranjaElemenata.getTip() == TipUvjeta.byDatum) {
                elementi = new List<IElement>();
                DateTime datum = DateTime.Parse(uvjetFiltriranjaElemenata.getIzraz());
                foreach (IElement item in sviElementi) {
                    if (item.getDatum() < datum)
                        elementi.Add(item);
                }
            }
            //TODO: imlementirati za ostale tipove
            //TODO: Iz baze povaditi elemente koji zadovoljavaju dan uvjet
            postaviTablicuIndeksa();
        }

        private void postaviTablicuIndeksa() {
            tablicaIndeksa = new Dictionary<int, int>();
            for (int i = 0; i < elementi.Count; i++) {
                tablicaIndeksa[elementi[i].getID()] = i;
            }
        }

        /// <summary>
        /// dohvaca element po rednom broju unutar repozitorija
        /// </summary>
        public IElement getElementByRedniBroj(int redniBroj) {
            if (redniBroj < 0 || redniBroj > elementi.Count - 1)
                throw new iznimke.RBElementNotExistException();
            return elementi[redniBroj];
        }

        public Uvjet getUvjet() {
            return uvjetFiltriranjaElemenata;
        }

        public IElement getElementByRedniBrojAndUvjet(int redniBroj, Uvjet uvjet) {
            if (!uvjetFiltriranjaElemenata.Equals(uvjet))
                setUvjet(uvjet);
            return getElementByRedniBroj(redniBroj);
        }

        /// <summary>
        /// vraca broj elemenata koji zadovoljava uvjet postavljen unutar repozitorija
        /// </summary>
        public int getBrojElemenata() {
            return elementi.Count;
        }

        public void updateElementKontrole(ElementKontrole eleKont) {
            throw new System.NotImplementedException();
        }

        public void removeElementKontrole(ElementKontrole eleKont) {
            throw new System.NotImplementedException();
        }

        public List<ElementKontrole> getEleKontroleByKontrola(Kontrola kontrola) {
            throw new System.NotImplementedException();
        }

        public ElementKontrole getEleKontroleByID(int idElementa) {
            throw new System.NotImplementedException();
        }
    }
}
